#ifndef __MSA311_H__
#define __MSA311_H__

#define MSA311_I2CADDR_DEFAULT_7 (0x62) ///< Fixed I2C address
#define MSA311_I2CADDR_DEFAULT_8 (0xC4) ///< Fixed I2C address

/*=========================================================================*/

#define MSA311_REG_RESET                    0x00    ///< Register soft reset
#define MSA311_REG_PARTID                   0x01    ///< Register that contains the part ID
#define MSA311_REG_OUT_X_L                  0x02    ///< Register address for X axis lower byte
#define MSA311_REG_OUT_X_H                  0x03    ///< Register address for X axis higher byte
#define MSA311_REG_OUT_Y_L                  0x04    ///< Register address for Y axis lower byte
#define MSA311_REG_OUT_Y_H                  0x05    ///< Register address for Y axis higher byte
#define MSA311_REG_OUT_Z_L                  0x06    ///< Register address for Z axis lower byte
#define MSA311_REG_OUT_Z_H                  0x07    ///< Register address for Z axis higher byte
#define MSA311_REG_MOTIONINT                0x09    ///< Register address for motion interrupt
#define MSA311_REG_DATAINT                  0x0A    ///< Register address for data interrupt
#define MSA311_REG_CLICKSTATUS              0x0B    ///< Register address for click/doubleclick status
#define MSA311_REG_ORIENTATION_STATUS       0x0C    ///< Register address for orientation status
#define MSA311_REG_RESRANGE                 0x0F    ///< Register address for resolution range
#define MSA311_REG_ODR                      0x10    ///< Register address for data rate setting
#define MSA311_REG_POWERMODE                0x11    ///< Register address for power mode setting
#define MSA311_REG_INTSET0                  0x16    ///< Register address for interrupt setting #0
#define MSA311_REG_INTSET1                  0x17    ///< Register address for interrupt setting #1
#define MSA311_REG_INTMAP0                  0x19    ///< Register address for interrupt map #0
#define MSA311_REG_INTMAP1                  0x1A    ///< Register address for interrupt map #1
#define MSA311_REG_TAPDUR                   0x2A    ///< Register address for tap duration
#define MSA311_REG_TAPTH                    0x2B    ///< Register address for tap threshold
#define MSA311_REG_ACTIVE_DURATION			0x27
#define MSA311_REG_ACTIVE_THRESHOLD			0x28

#define MSA311_REG_OFFSET_X                 0x38
#define MSA311_REG_OFFSET_Y                 0x39
#define MSA311_REG_OFFSET_Z                 0x3A

#define MSA311_POWER_MODE_MSAK				0x3F
#define MSA311_POWER_MODE_SHIFT				0x05u

#define MSA311_REG_FREE_FALL_DURATION		0x22
#define MSA311_REG_FREE_FALL_THRESHOLD		0x23
#define MSA311_REG_FREE_FALL_HY				0x24


/** The accelerometer power mode */
typedef enum {
  	MSA311_NORMALMODE 	= 0x00,   	    ///< Normal (high speed) mode
  	MSA311_LOWPOWERMODE 	= 0x40, 	///< Low power (slow speed) mode
  	MSA311_SUSPENDMODE 	= 0xC0, 	    ///< Suspend (sleep) mode
} msa311_powermode_t;


#define MSA311_AXES_ENABLE_MSAK				0x1F
typedef enum{
	AXES_DISABLE 	= 0x00,
	AXES_ENABLE 	= 0xE0,
}msa311_axes_state_t;

#define MSA311_DATA_RATE_MASK				0xF0			
/** The accelerometer data rate */
typedef enum {
  	MSA311_DATARATE_1_HZ 			= 0x00,     	///<  1 Hz
  	MSA311_DATARATE_1_95_HZ 		= 0x01,  		///<  1.95 Hz
  	MSA311_DATARATE_3_9_HZ 			= 0x02,   		///<  3.9 Hz
	MSA311_DATARATE_7_81_HZ 		= 0x03,  		///<  7.81 Hz
	MSA311_DATARATE_15_63_HZ 		= 0x04, 		///<  15.63 Hz
	MSA311_DATARATE_31_25_HZ 		= 0x05, 		///<  31.25 Hz
	MSA311_DATARATE_62_5_HZ 		= 0x06,  		///<  62.5 Hz
	MSA311_DATARATE_125_HZ 			= 0x07,   		///<  125 Hz
	MSA311_DATARATE_250_HZ 			= 0x08,   		///<  250 Hz
	MSA311_DATARATE_500_HZ 			= 0x09,   		///<  500 Hz
	MSA311_DATARATE_1000_HZ 		= 0x0A,  		///<  1000 Hz
} msa311_dataRate_t;

#define MSA311_BAND_WIDTH_MASK				0xE1
/** The accelerometer bandwidth */
typedef enum {
	MSA301_BANDWIDTH_1_95_HZ 		= 0x00,  	///<  1.95 Hz
	MSA301_BANDWIDTH_3_9_HZ 		= 0x06,   	///<  3.9 Hz
	MSA301_BANDWIDTH_7_81_HZ 		= 0x08,  	///<  7.81 Hz
	MSA301_BANDWIDTH_15_63_HZ 	= 0x0A, 	///<  15.63 Hz
	MSA301_BANDWIDTH_31_25_HZ 	= 0x0C, 	///<  31.25 Hz
	MSA301_BANDWIDTH_62_5_HZ 		= 0x0E,  	///<  62.5 Hz
	MSA301_BANDWIDTH_125_HZ 		= 0x10,   	///<  125 Hz
	MSA301_BANDWIDTH_250_HZ 		= 0x12,   	///<  250 Hz
	MSA301_BANDWIDTH_500_HZ 		= 0x14,   	///<  500 Hz
} msa301_bandwidth_t;

#define MSA311_RANG_MASK					0xFC
/** The accelerometer ranges */
typedef enum {
	MSA311_RANGE_2_G 			= 0x00,  		///< +/- 2g (default value)
	MSA311_RANGE_4_G 			= 0x01,  		///< +/- 4g
	MSA311_RANGE_8_G 			= 0x02,  		///< +/- 8g
	MSA311_RANGE_16_G			= 0x03, 		///< +/- 16g
} msa311_range_t;

#define MSA311_TAP_DUR_MASK      			0xF8
/** Tap duration parameter */
typedef enum {
	MSA311_TAPDUR_50_MS 		= 0x00,  		///< 50 millis
	MSA311_TAPDUR_100_MS 		= 0x01, 		///< 100 millis
	MSA311_TAPDUR_150_MS 		= 0x02, 		///< 150 millis
	MSA311_TAPDUR_200_MS 		= 0x03, 		///< 200 millis
	MSA311_TAPDUR_250_MS 		= 0x04, 		///< 250 millis
	MSA311_TAPDUR_375_MS 		= 0x05, 		///< 375 millis
	MSA311_TAPDUR_500_MS 		= 0x06, 		///< 500 millis
	MSA311_TAPDUR_700_MS 		= 0x07, 		///< 50 millis700 millis
} msa311_tapduration_t;

#define MSA311_TAP_QUITE_MASK				0x7F
typedef enum{
	MSA311_TAPQUITE_20_MS		= 0x80,
	MSA311_TAPQUITE_30_MS		= 0x00,
}msa311_tapquite_t;

#define MSA311_TAP_SHOCK_MASK				0xBF	

typedef enum{
	MSA311_TAPSHOCK_50_MS   	= 0x00,
	MSA311_TAPSHOCK_70_MS		= 0x40,

}msa311_tapshock_t;

typedef enum
{
    MSA311_BOOL_FALSE = 0x00,        /**< false */
    MSA311_BOOL_TRUE  = 0x01,        /**< true */
} msa311_bool_t;

typedef enum
{
    MSA311_INTERRUPT_FREE_FALL 	= 0x00,        /**< free fall */
	MSA311_INTERRUPT_ACTIVE		= 0x02,
	MSA311_INTERRUPT_D_TAP		= 0x04,
	MSA311_INTERRUPT_S_TAP		= 0x05,
	MSA311_INTERRUPT_ORIENT		= 0x06,

} msa311_interrupt_map0_t;

typedef enum
{
    MSA311_INTERRUPT_ACTIVE_EN_X 	= 0x00, 
	MSA311_INTERRUPT_ACTIVE_EN_Y 	= 0x01,    
    MSA311_INTERRUPT_ACTIVE_EN_Z 	= 0x02,   
	MSA311_INTERRUPT_D_TAP_EN		= 0x04,
	MSA311_INTERRUPT_S_TAP_EN		= 0x05,
	MSA311_INTERRUPT_ORIENT_EN		= 0x06,
} msa311_interrupt_sw0_t;

typedef enum
{
    MSA311_INTERRUPT_FREE_FALLEN 	= 0x03, 
	MSA311_INTERRUPT_NEW_DATA_EN 	= 0x04,    
} msa311_interrupt_sw1_t;


typedef enum{
	MSA311_INT_S_TAP_MESSAGE   		= 0x00,
	MSA311_INT_D_TAP_MESSAGE   		= 0x01,

}msa311_int_message_type;

typedef enum
{
	MSA311_FREE_FALL_INT_STATE 		= 0x00,
	MSA311_ACTIVE_INT_STATE			= 0x02,
	MSA311_D_TAP_INT_STATE			= 0x04,
	MSA311_S_TAP_INT_STATE			= 0x05,
	MSA311_ORIENT_INT_STATE			= 0x06,

}msa311_int_state_t;

#define MSA311_ACTIVE_DURATION_MASK   0xFCu
typedef enum
{
	MSA311_ACTIVE_DURATION_0 		= 0x00,
	MSA311_ACTIVE_DURATION_1 		= 0x01,
	MSA311_ACTIVE_DURATION_2 		= 0x02,
	MSA311_ACTIVE_DURATION_3 		= 0x03,
}msa311_active_duration_t;

// golbal function
void Msa311_Init(void);
void handle_int_message(void);
bool Msa311_GetXYZData();
#endif